﻿using System;
using System.Diagnostics;

namespace Tables
{
    class HTable : IDisposable
    {
        public HTable()
            : this (sizeHTable)
        {
        }
        public HTable(int size)
        {
            _aList = new List[size];
            init();
        }
        /// <summary>
        /// Returns a short list of possible matches
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public List Find(string str)
        {
            return Find(str, str.Length);
        }
        /// <summary>
        /// Returns a short list of matches
        /// </summary>
        /// <param name="str"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public List Find(string str, int len)
        {
            int i = _Hash(str);
            return _aList[i];
        }
        /// <summary>
        /// Adds another string mapping
        /// </summary>
        /// <param name="str"></param>
        /// <param name="id"></param>
        public void Add(string str, int id)
        {
            int i = _Hash(str);
            _aList[i].Add(id);
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    //disposed managed resource
                    _aList = null;
                }
                // release unmanaged resource
            }
            _disposed = true;

            // if available, call to base class
            // base.Dispose(disposing);
        }


        private bool _disposed = false;
        private const int sizeHTable = 127; // 127 = 2^7 - 1
        private List[] _aList;
        private int _Hash(string str)
        {
            // implentation of the shift-and-add algorithm,
            // one of the best string randomizers
            Debug.Assert(str.Length != 0 && str[0] != null);
            UInt32 h = str[0];
            for (int i = 1; i < str.Length; ++i)
                h = (h << 4) + str[i];
            Debug.Assert(h >= 0);
            return (int)h % sizeHTable;
        }
        private void init()
        {
            for (int i = 0;
                i < _aList.Length;
                ++i)
            {
                _aList[i] = new List();
            }
        }

    }
}
